﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using SystemDiagramNew.SystemDiagramLegend;
using SystemDiagramNew.SystemDiagramLegend.DataDefine;
using SystemDiagramNew.Utils;

namespace SystemDiagramNew.TypeDefinition
{
	public class Node
	{
		public Element Component { get; private set; }

		public Node.NodeType TheNodeType
		{
			get
			{
				return this.m_NodeType;
			}
		}

		public XYZ Position { get; set; }

		public List<PipeInfo> PipeList
		{
			get
			{
				return this.m_PipeList;
			}
		}

		internal static ExternalCommandData Revit { get; set; }

		internal static Document Document
		{
			get
			{
				return Node.Revit.Application.ActiveUIDocument.Document;
			}
		}

		internal Element Element
		{
			get
			{
				return this.Component;
			}
		}

		internal FamilyInstance Instance
		{
			get
			{
				return this.Element as FamilyInstance;
			}
		}

		internal FamilySymbol Symbol
		{
			get
			{
				return this.Instance.Symbol;
			}
		}

		internal Family Family
		{
			get
			{
				return this.Symbol.Family;
			}
		}

		internal string FamilyName
		{
			get
			{
				return this.Family.Name;
			}
		}

		internal bool IsOnStandPipe { get; set; }

		internal bool IsAccessory
		{
			get
			{
				return this.TheNodeType == Node.NodeType.NT_PIPEACCESSORY;
			}
		}

		internal bool IsConnectPosition { get; private set; }

		internal CurveArray LegendCurves
		{
			get
			{
				CurveArray result;
				if ((result = this._legendCurves) == null)
				{
					result = (this._legendCurves = new CurveArray());
				}
				return result;
			}
		}

		internal List<ElementId> LegendAttachedIds
		{
			get
			{
				List<ElementId> result;
				if ((result = this._legendAttachedIds) == null)
				{
					result = (this._legendAttachedIds = new List<ElementId>());
				}
				return result;
			}
		}

		private double NodeAngle { get; set; }

		public Node()
		{
			this.Position = null;
			this.Component = null;
			this.IsConnectPosition = false;
		}

		public Node(Node.NodeType type, Element component, XYZ ptPosition, List<PipeInfo> pipeList)
		{
			this.m_NodeType = type;
			this.Component = component;
			this.Position = ptPosition;
			this.m_PipeList = pipeList;
			this.IsConnectPosition = this.CheckAccessoryNodePosition();
		}

		public void AddPipe(PipeInfo pipe)
		{
			this.m_PipeList.Add(pipe);
		}

		private bool CheckAccessoryNodePosition()
		{
			bool flag = false;
			if (this.IsAccessory && this.FamilyName == "上接水角阀" && this.m_PipeList.Count == 0)
			{
				XYZ xyz = (this.Instance.Location as LocationPoint).Point;
				foreach (object obj in this.Instance.MEPModel.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
					if (connector.IsConnected)
					{
						xyz = connector.Origin;
						break;
					}
				}
				flag = xyz.IsAlmostEqualTo(this.Position);
				if (flag)
				{
					this.Relocate();
				}
			}
			return flag;
		}

		private void Relocate()
		{
			ConnectorSet connectors = this.Instance.MEPModel.ConnectorManager.Connectors;
			Connector connector = null;
			foreach (object obj in connectors)
			{
				Connector connector2 = (Connector)obj;
				if (connector2.IsConnected)
				{
					foreach (object obj2 in connector2.AllRefs)
					{
						Connector connector3 = (Connector)obj2;
						if (connector3.Owner.Id.IntegerValue != this.Component.Id.IntegerValue)
						{
							connector = connector3;
							break;
						}
					}
				}
			}
			if (connector != null)
			{
				FamilyInstance familyInstance = connector.Owner as FamilyInstance;
				if (familyInstance != null)
				{
					this.Position = (familyInstance.Location as LocationPoint).Point;
				}
			}
		}

		public int MaxPipeDiameter()
		{
			int num = 0;
			foreach (PipeInfo pipeInfo in this.m_PipeList)
			{
				if (pipeInfo.Diameter > num)
				{
					num = pipeInfo.Diameter;
				}
			}
			return num;
		}

		private Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector != null && connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		public bool IsEqual(Node rhs)
		{
			return (this.Component != null || rhs.Component != null) && this.Component != null && rhs.Component != null && this.Component.Id.IntegerValue == rhs.Component.Id.IntegerValue;
		}

		public bool Finded(ElementId id)
		{
			return (this.Component != null || !(id == null)) && this.Component != null && !(id == null) && this.Component.Id.IntegerValue == id.IntegerValue;
		}

		public int FindLinkPipeWithOtherNode(XYZ ptOtherNode)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < this.m_PipeList.Count; i++)
			{
				XYZ xyz = this.m_PipeList[i].CurEndPoint(this.Position);
				if (xyz != null && ptOtherNode.IsAlmostEqualTo(xyz))
				{
					list.Add(i);
				}
			}
			if (list.Count < 1)
			{
				return -1;
			}
			return list[list.Count - 1];
		}

		public void Transform(Transform transform)
		{
			int i = 0;
			if (this.m_NodeType != Node.NodeType.NT_PIPEFITTING_TRAP_P)
			{
				if (this.m_NodeType != Node.NodeType.NT_PIPEFITTING_TRAP_S)
				{
					XYZ position = this.Position;
					this.Position = Geometry.TransformPoint(this.Position, transform);
					while (i < this.m_PipeList.Count)
					{
						this.m_PipeList[i].SetCurStartPoint(position, this.Position);
						i++;
					}
					return;
				}
			}
			while (i < this.m_PipeList.Count)
			{
				PipeInfo pipeInfo = this.m_PipeList[i];
				XYZ xyz = pipeInfo.CurStartPoint(this.Position);
				xyz = Geometry.TransformPoint(xyz, transform);
				pipeInfo.SetCurStartPoint(this.Position, xyz);
				i++;
			}
			this.Position = Geometry.TransformPoint(this.Position, transform);
		}

		public void TransformShaftSide(double angle)
		{
			int i = 0;
			if (this.m_NodeType != Node.NodeType.NT_PIPEFITTING_TRAP_P)
			{
				if (this.m_NodeType != Node.NodeType.NT_PIPEFITTING_TRAP_S)
				{
					XYZ position = this.Position;
					this.Position = Geometry.TransformPointToShaftSide(this.Position, angle);
					while (i < this.m_PipeList.Count)
					{
						this.m_PipeList[i].SetCurStartPoint(position, this.Position);
						i++;
					}
					return;
				}
			}
			while (i < this.m_PipeList.Count)
			{
				PipeInfo pipeInfo = this.m_PipeList[i];
				XYZ xyz = pipeInfo.CurStartPoint(this.Position);
				xyz = Geometry.TransformPointToShaftSide(xyz, angle);
				pipeInfo.SetCurStartPoint(this.Position, xyz);
				i++;
			}
			this.Position = Geometry.TransformPointToShaftSide(this.Position, angle);
		}

		public static Node.NodeType GetNodeType(FamilyInstance instance)
		{
			if (instance == null || instance.Category == null)
			{
				return Node.NodeType.NT_NULL;
			}
			Node.NodeType result = Node.NodeType.NT_NULL;
			if (Node.GetNodeTypeByFamilyName(out result, instance))
			{
				return result;
			}
			int integerValue = instance.Category.Id.IntegerValue;
			if (integerValue <= -2008055)
			{
				if (integerValue == -2008099)
				{
					return Node.NodeType.NT_SPRINKLERS;
				}
				if (integerValue == -2008055)
				{
					return Node.GetAccessoryType(instance);
				}
			}
			else
			{
				if (integerValue == -2008049)
				{
					return Node.GetFittingType(instance);
				}
				if (integerValue == -2001160)
				{
					return Node.NodeType.NT_PLUMBING_FIXTURES;
				}
				if (integerValue == -2001140)
				{
					return Node.NodeType.NT_MECHANICAL_EQUIPMENT;
				}
			}
			return Node.NodeType.NT_NULL;
		}

		private static bool GetNodeTypeByFamilyName(out Node.NodeType nt, FamilyInstance instance)
		{
			nt = Node.NodeType.NT_NULL;
			string name = instance.Symbol.Family.Name;
			if (name.Contains("检查口"))
			{
				nt = Node.NodeType.NT_PIPEACCESSORY_CheckHole;
				return true;
			}
			if (name.Contains("存水弯"))
			{
				if (name.Contains("p") || name.Contains("P"))
				{
					nt = Node.NodeType.NT_PIPEFITTING_TRAP_P;
				}
				else
				{
					nt = Node.NodeType.NT_PIPEFITTING_TRAP_S;
				}
				return true;
			}
			if (name.Contains("地漏"))
			{
				nt = Node.NodeType.NT_PIPEACCESSORY_FloorDrain;
				return true;
			}
			if (name.Contains("清扫口"))
			{
				nt = Node.NodeType.NT_PIPEACCESSORY_CleanOut;
				return true;
			}
			return false;
		}

		private static Node.NodeType GetAccessoryType(FamilyInstance instance)
		{
			if (instance.Symbol.Family.Name.Contains("检查口"))
			{
				return Node.NodeType.NT_PIPEACCESSORY_CheckHole;
			}
			return Node.NodeType.NT_PIPEACCESSORY;
		}

		private static Node.NodeType GetFittingType(FamilyInstance instance)
		{
			string name = instance.Symbol.Family.Name;
			if (name.Contains("存水弯"))
			{
				if (name.Contains("p") || name.Contains("P"))
				{
					return Node.NodeType.NT_PIPEFITTING_TRAP_P;
				}
				return Node.NodeType.NT_PIPEFITTING_TRAP_S;
			}
			else
			{
				MechanicalFitting mechanicalFitting = instance.MEPModel as MechanicalFitting;
				if (mechanicalFitting == null)
				{
					return Node.NodeType.NT_NULL;
				}
                if ((int)mechanicalFitting.PartType == 7)
				{
					return Node.NodeType.NT_PIPE_TRANSITION_PIECE;
				}
				return Node.NodeType.NT_PIPEFITTING;
			}
		}

		private double GetAccessoryAngle()
		{
			IEnumerable<Connector> source = this.Instance.MEPModel.ConnectorManager.Connectors.OfType<Connector>();
			if (source.Count<Connector>() != 2)
			{
				return 0.0;
			}
			Connector connector = source.ElementAt(0);
			Connector connector2 = source.ElementAt(1);
			XYZ xyz = connector.Origin - connector2.Origin;
			if (Geometry.IsParallel(xyz, XYZ.BasisZ))
			{
				return Math.PI*.5;
			}
			return xyz.GetXY().AngleTo(XYZ.BasisX);
		}

		internal LegendDirection GetLegendDirection(double shaftSideAngle)
		{
			this.IsOnStandPipe = false;
			List<PipeInfo> pipeList = this.PipeList;
			if (pipeList.Count != 1 && pipeList.Count != 2)
			{
				return LegendDirection.BottomLink;
			}
			PipeInfo pipeInfo = pipeList[0];
			XYZ pt = pipeInfo.CurEndPoint(this.Position);
			this.IsOnStandPipe = pipeInfo.IsStandpipe();
			this.NodeAngle = (this.IsAccessory ? this.GetAccessoryAngle() : Geometry.getAngle(pt.GetXY(), this.Position.GetXY()));
			double[] array = new double[]
			{
				Math.PI,
				0.0,
				0.0,
				0.0,
				Math.PI*.5,
				4.71238898038469,
				Math.PI*2
			};
			array[1] = shaftSideAngle;
			array[3] = shaftSideAngle + Math.PI;
			double[] array2 = array;
			double val = double.MaxValue;
			int i = 0;
			int num = 0;
			while (i < array2.Length)
			{
				double num2 = Math.Abs(array2[i] - this.NodeAngle);
				if (Geometry.LessThan(num2, val))
				{
					val = num2;
					num = i;
				}
				i++;
			}
			switch (num)
			{
			case 0:
				return LegendDirection.LeftLink;
			case 1:
			case 4:
				return LegendDirection.TopLink;
			case 2:
			case 6:
				return LegendDirection.RightLink;
			}
			return LegendDirection.BottomLink;
		}

		internal LegendDirection GetLengendDirctionAfterTransfered(double shaftSideAngle)
		{
			this.IsOnStandPipe = false;
			if (this.IsAccessory)
			{
				this.NodeAngle = this.GetAccessoryAngleAfterTransfered(shaftSideAngle);
				return this.GetDirection(this.NodeAngle);
			}
			List<PipeInfo> pipeList = this.PipeList;
			if (pipeList.Count != 1 && pipeList.Count != 2)
			{
				return LegendDirection.BottomLink;
			}
			PipeInfo pipeInfo = pipeList[0];
			XYZ pt = pipeInfo.CurEndPoint(this.Position);
			this.IsOnStandPipe = pipeInfo.IsStandpipe();
			this.NodeAngle = Geometry.getAngle(pt.GetXY(), this.Position.GetXY());
			return this.GetDirection(this.NodeAngle);
		}

		internal LegendDirection GetDirection(double angle)
		{
			LegendDirection result = LegendDirection.BottomLink;
			if ((Geometry.Greaterthan_Or_Equal(angle, 5.497787143782138) && Geometry.Lessthan_Or_Equal(angle, Math.PI*2)) || (Geometry.Greaterthan_Or_Equal(angle, 0.0) && Geometry.LessThan(angle, 0.78539816339744828)))
			{
				result = LegendDirection.RightLink;
			}
			else if (Geometry.Greaterthan_Or_Equal(angle, 0.78539816339744828) && Geometry.LessThan(angle, 2.3561944901923448))
			{
				result = LegendDirection.TopLink;
			}
			else if (Geometry.Greaterthan_Or_Equal(angle, 2.3561944901923448) && Geometry.LessThan(angle, 3.9269908169872414))
			{
				result = LegendDirection.LeftLink;
			}
			else if (Geometry.Greaterthan_Or_Equal(angle, 3.9269908169872414) && Geometry.LessThan(angle, 5.497787143782138))
			{
				result = LegendDirection.BottomLink;
			}
			return result;
		}

		internal double GetAccessoryAngleAfterTransfered(double shaftSideAngle)
		{
			IEnumerable<Connector> source = this.Instance.MEPModel.ConnectorManager.Connectors.OfType<Connector>();
			if (source.Count<Connector>() != 2)
			{
				return 0.0;
			}
			Connector connector = source.ElementAt(0);
			Connector connector2 = source.ElementAt(1);
			double angle = shaftSideAngle / Math.PI * 180.0;
			XYZ xyz = connector.Origin;
			XYZ xyz2 = connector2.Origin;
			XYZ xyz3 = connector.Origin - connector2.Origin;
			if (!Geometry.IsEqual(xyz3.Y, 0.0))
			{
				xyz = Geometry.TransformPointToShaftSide(connector.Origin.GetXY(), angle);
				xyz2 = Geometry.TransformPointToShaftSide(connector2.Origin.GetXY(), angle);
			}
            if ((int)connector.Direction == 1)
			{
				xyz3 = xyz2 - xyz;
			}
			else
			{
				xyz3 = xyz - xyz2;
			}
			XYZ xy = xyz3.GetXY();
			return Geometry.formatAngle(YJKRevitTools.GetTwoXYVectorAngle(XYZ.BasisX, xy));
		}

		internal bool Draw(Autodesk.Revit.DB.View drawView, double shaftSideAngle, DrawingKit.LegendInfoFileManager legendInfoManager, Transform scaleMatrix)
		{
			if (this.Instance == null)
			{
				return false;
			}
			DrawingKit.Print("节点名称：" + this.Instance.Symbol.Family.Name);
			LegendDirection lengendDirctionAfterTransfered = this.GetLengendDirctionAfterTransfered(shaftSideAngle);
			Transform transform = this.GetTransform(lengendDirctionAfterTransfered);
			bool flag = false;
			switch (this.TheNodeType)
			{
			case Node.NodeType.NT_PLUMBING_FIXTURES:
				flag = this.DrawFixtures(drawView, shaftSideAngle, scaleMatrix);
				DrawingKit.Print("节点类型：卫浴");
				break;
			case Node.NodeType.NT_PIPEFITTING_TRAP_S:
				DrawingKit.Print("节点类型：S弯");
				return this.DrawTrapS(drawView, shaftSideAngle, scaleMatrix);
			case Node.NodeType.NT_PIPEFITTING_TRAP_P:
				DrawingKit.Print("节点类型：P弯");
				return this.DrawTrapP(drawView, shaftSideAngle, scaleMatrix);
			case Node.NodeType.NT_PIPEACCESSORY_CheckHole:
				DrawingKit.Print("节点类型：检查口");
				return this.DrawCheckHole(drawView, shaftSideAngle, scaleMatrix);
			case Node.NodeType.NT_PIPEACCESSORY_FloorDrain:
				flag = this.DrawFloorDrain(drawView, shaftSideAngle, scaleMatrix);
				DrawingKit.Print("节点类型：地漏");
				break;
			case Node.NodeType.NT_PIPEACCESSORY_CleanOut:
				flag = this.DrawCleanOut(drawView, shaftSideAngle, scaleMatrix);
				DrawingKit.Print("节点类型：清扫口");
				break;
			}
			if (flag)
			{
				return true;
			}
			DrawingKit.Print("节点-setp-1");
			LegendGroup legendGroup = null;
			string text = null;
			if (this.TheNodeType == Node.NodeType.NT_PIPEACCESSORY)
			{
				DrawingKit.Print("节点类型：NT_PIPEACCESSORY-卫浴");
				string paramName = "对应卫浴";
				Parameter parameter = this.Instance.GetParameter(paramName);
				if (parameter != null)
				{
					DrawingKit.Print("节点类型：对应卫浴名称-" + parameter.AsString());
					SetSanitaryData setSanitaryData = YJKRevitTools.GetSetSanitaryData(Node.Document, parameter.AsString());
					if (setSanitaryData != null)
					{
						DrawingKit.Print("节点类型：卫浴缩写-" + setSanitaryData.ShortName);
						legendGroup = legendInfoManager.GetLegendGroupByName(setSanitaryData.TerminalLegendName);
						text = setSanitaryData.ShortName;
					}
				}
				else
				{
					DrawingKit.Print("节点类型：对应卫浴参数为空");
				}
			}
			DrawingKit.Print("节点-setp-2");
			if (legendGroup == null)
			{
				legendGroup = legendInfoManager.GetLegendGroupByFamilyName(this.FamilyName);
				if (legendGroup == null)
				{
					return false;
				}
			}
			Legend legend = legendGroup.GetLegend(lengendDirctionAfterTransfered);
			CurveArray legendCurveAry = this.GetLegendCurveAry(legend, scaleMatrix);
			DetailCurveArray detailCurveArray = this.DrawCurves(drawView, legendCurveAry, lengendDirctionAfterTransfered, transform);
			Transform transform2 = Autodesk.Revit.DB.Transform.CreateTranslation(-legend.Position);
			transform = transform.Multiply(transform2);
			List<TextNote> list = this.DrawText(drawView, legend, scaleMatrix, transform);
			Transform transform3 = RevitVersionFuncs.CreateTranslation(-legend.Position.GetXY());
			Transform transform4 = Autodesk.Revit.DB.Transform.Identity.Multiply(scaleMatrix);
			transform4 = transform4.Multiply(transform3);
			transform = this.GetTransform(lengendDirctionAfterTransfered);
			List<FilledRegion> list2 = this.DrawRegion(drawView, legend, transform4, transform);
			string text2 = "";
			DrawingKit.Print("卫浴缩写：start");
			FamilySymbol familySymbolByName = YJKRevitTools.GetFamilySymbolByName("EquipmentSanitary", "卫浴缩写", Node.Document, ref text2);
			if (familySymbolByName != null && !string.IsNullOrEmpty(text))
			{
				DrawingKit.Print("卫浴缩写：族和缩写都不为空");
				XYZ xyz = new XYZ(0.0, 2.0, 0.0);
				XYZ xyz2 = this.Position + xyz;
				FamilyInstance familyInstance = Node.Document.Create.NewFamilyInstance(xyz2, familySymbolByName, drawView);
				if (familyInstance != null)
				{
					DrawingKit.Print("卫浴缩写：创建缩写族成功");
					Parameter parameter2 = familyInstance.GetParameter("文字");
					if (parameter2 != null)
					{
						DrawingKit.Print("卫浴缩写：设置缩写族参数成功");
						parameter2.Set(text);
					}
				}
			}
			else
			{
				if (familySymbolByName == null)
				{
					DrawingKit.Print("卫浴缩写：加载族缩写失败");
				}
				if (string.IsNullOrEmpty(text))
				{
					DrawingKit.Print("卫浴缩写：卫浴缩写为空");
				}
			}
			Element[] array = (from pi in this.PipeList
			select pi.Component).ToArray<Element>();
			List<ElementId> list3 = new List<ElementId>();
			foreach (Element element in array)
			{
				list3.Add(element.Id);
			}
			foreach (object obj in detailCurveArray)
			{
				ExtensibleStorageManager.WriteModelInfo(obj as DetailCurve, false, drawView.Id, this.Instance.Id, list3);
			}
			foreach (TextNote elem in list)
			{
				ExtensibleStorageManager.WriteModelInfo(elem, false, drawView.Id, this.Instance.Id, list3);
			}
			foreach (FilledRegion elem2 in list2)
			{
				ExtensibleStorageManager.WriteModelInfo(elem2, false, drawView.Id, this.Instance.Id, list3);
			}
			return true;
		}

		private double GetRadius(Autodesk.Revit.DB.View drawView)
		{
			return 4.0.MMtoFeet() * (double)drawView.Scale / 2.0;
		}

		internal bool DrawFixtures(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			string text = YJKRevitTools.GetSetSanitaryShortName(PipeInfo.CurDoc, this.Element);
			if (text.IsEmpty<char>())
			{
				text = "?";
			}
			double radius = this.GetRadius(drawView);
			XYZ xyz = this.Position.GetXY() + this._vecY * radius;
			string text2 = "";
			FamilySymbol familySymbolByName = YJKRevitTools.GetFamilySymbolByName("EquipmentSanitary", "卫浴缩写", Node.Document, ref text2);
			if (familySymbolByName != null)
			{
				FamilyInstance familyInstance = Node.Document.Create.NewFamilyInstance(xyz, familySymbolByName, drawView);
				if (familyInstance != null)
				{
					Parameter parameter = familyInstance.GetParameter("文字");
					if (parameter != null && !string.IsNullOrEmpty(text))
					{
						parameter.Set(text);
					}
				}
			}
			if (this.PipeList != null)
			{
				(from pi in this.PipeList
				select pi.Component).ToArray<Element>();
			}
			return true;
		}

		internal bool DrawFloorDrain(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			double num = (1.0 * (double)drawView.Scale).MMtoFeet() / 2.0;
			XYZ xyz = new XYZ(1.0, 0.0, 0.0);
			XYZ xyz2 = new XYZ(0.0, 1.0, 0.0);
			XYZ xyz3 = this.Position.GetXY() + xyz2 * num;
			Arc arc = Arc.Create(xyz3, num, Math.PI, Math.PI*2, XYZ.BasisX, XYZ.BasisY);
			DetailCurve elem = Node.Document.Create.NewDetailCurve(drawView, arc);
			double num2 = (0.4 * (double)drawView.Scale).MMtoFeet();
			XYZ start = xyz3 - xyz * (num + num2);
			XYZ end = xyz3 + xyz * (num + num2);
			DetailCurve elem2 = drawView.NewDetailLine(start, end);
			if (this.PipeList != null)
			{
				Element[] array = (from pi in this.PipeList
				select pi.Component).ToArray<Element>();
				List<ElementId> list = new List<ElementId>();
				foreach (Element element in array)
				{
					list.Add(element.Id);
				}
				ExtensibleStorageManager.WriteModelInfo(elem, false, drawView.Id, this.Instance.Id, list);
				ExtensibleStorageManager.WriteModelInfo(elem2, false, drawView.Id, this.Instance.Id, list);
			}
			return true;
		}

		internal bool DrawCleanOut(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			double num = (1.4 * (double)drawView.Scale).MMtoFeet();
			XYZ xy = this.Position.GetXY();
			(0.4 * (double)drawView.Scale).MMtoFeet();
			XYZ start = xy - this._vecX * num / 2.0;
			XYZ end = xy + this._vecX * num / 2.0;
			DetailCurve elem = drawView.NewDetailLine(start, end);
			double num2 = (1.0 * (double)drawView.Scale).MMtoFeet();
			XYZ xyz = xy + this._vecY * (0.5 * (double)drawView.Scale).MMtoFeet();
			XYZ start2 = xyz - this._vecX * num2 / 2.0;
			XYZ end2 = xyz + this._vecX * num2 / 2.0;
			DetailCurve elem2 = drawView.NewDetailLine(start2, end2);
			if (this.PipeList != null)
			{
				Element[] array = (from pi in this.PipeList
				select pi.Component).ToArray<Element>();
				List<ElementId> list = new List<ElementId>();
				foreach (Element element in array)
				{
					list.Add(element.Id);
				}
				ExtensibleStorageManager.WriteModelInfo(elem, false, drawView.Id, this.Instance.Id, list);
				ExtensibleStorageManager.WriteModelInfo(elem2, false, drawView.Id, this.Instance.Id, list);
			}
			return true;
		}

		internal bool DrawTrapP(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			return false;
		}

		internal bool DrawTrapS(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			return false;
		}

		internal bool DrawCheckHole(Autodesk.Revit.DB.View drawView, double shaftSideAngle, Transform scaleMatrix)
		{
			if (Node._checkHoles == null)
			{
				Node._checkHoles = new Dictionary<ElementId, Node.CheckHoleData>();
			}
			Node.CheckHoleData checkHoleData = null;
			if (!Node._checkHoles.TryGetValue(this.Element.Id, out checkHoleData))
			{
				checkHoleData = new Node.CheckHoleData
				{
					elementId = this.Element.Id
				};
				Node._checkHoles.Add(this.Element.Id, checkHoleData);
			}
			double num = (1.0 * (double)drawView.Scale).MMtoFeet();
			XYZ xyz = this.Position.GetXY();
			XYZ xyz2 = xyz + this._vecY * num;
			XYZ xyz3 = xyz2 + this._vecY * num;
			foreach (PipeInfo pipeInfo in this.PipeList)
			{
				XYZ xy = pipeInfo.CurStartPoint(this.Position).GetXY();
				checkHoleData.SetPoint(xy);
			}
			if (checkHoleData.IsValid)
			{
				xyz = checkHoleData.P1;
				xyz3 = checkHoleData.P2;
				xyz2 = xyz + (xyz3 - xyz) / 2.0;
				DetailCurve elem = drawView.NewDetailLine(xyz, xyz3);
				XYZ xyz4 = xyz2 + this._vecX * num;
				DetailCurve elem2 = drawView.NewDetailLine(xyz2, xyz4);
				XYZ start = xyz4 + this._vecY * num * 0.5;
				XYZ end = xyz4 - this._vecY * num * 0.5;
				DetailCurve elem3 = drawView.NewDetailLine(start, end);
				if (this.PipeList != null)
				{
					Element[] array = (from pi in this.PipeList
					select pi.Component).ToArray<Element>();
					List<ElementId> list = new List<ElementId>();
					foreach (Element element in array)
					{
						list.Add(element.Id);
					}
					ExtensibleStorageManager.WriteModelInfo(elem, false, drawView.Id, this.Instance.Id, list);
					ExtensibleStorageManager.WriteModelInfo(elem2, false, drawView.Id, this.Instance.Id, list);
					ExtensibleStorageManager.WriteModelInfo(elem3, false, drawView.Id, this.Instance.Id, list);
				}
				return true;
			}
			return true;
		}

		private Transform GetTransform(LegendDirection lengendDir)
		{
			Transform transform = Autodesk.Revit.DB.Transform.CreateTranslation(this.Position);
			if (this.IsAccessory && this.IsOnStandPipe && lengendDir == LegendDirection.TopLink && this.PipeList.Count == 2)
			{
				Transform transform2 = RevitVersionFuncs.CreateRotationAtPoint(XYZ.BasisZ, 0.78539816339744828, XYZ.Zero);
				transform = transform.Multiply(transform2);
			}
			return transform;
		}

		private CurveArray GetLegendCurveAry(Legend legend, Transform scaleMatrix)
		{
			CurveArray curveArray = new CurveArray();
			Transform transform = RevitVersionFuncs.CreateTranslation(-legend.Position.GetXY());
			Transform transform2 = Autodesk.Revit.DB.Transform.Identity.Multiply(scaleMatrix);
			transform2 = transform2.Multiply(transform);
			foreach (EdgeInfo edgeInfo in from curveInfo in legend.CurveInfoList
			select curveInfo.CurveObj)
			{
				if (Geometry.IsEqual(edgeInfo.Bulge, 0.0))
				{
					Line line = edgeInfo.CreateLegendLine(transform2);
					if (null != line)
					{
						curveArray.Append(line);
					}
				}
				else
				{
					Arc arc = Geometry.CreateArc(edgeInfo.StartPoint.GetXY(), edgeInfo.EndPoint.GetXY(), edgeInfo.Bulge, transform2);
					this.AppendArcLines(arc, curveArray);
				}
			}
			return curveArray;
		}

		private void AppendArcLines(Arc arc, CurveArray curveAry)
		{
			if (null == arc)
			{
				return;
			}
			IList<XYZ> list = arc.Tessellate();
			for (int i = 0; i < list.Count - 1; i++)
			{
				try
				{
					Line line = Line.CreateBound(list[i], list[i + 1]);
					if (!(null == line))
					{
						curveAry.Append(line);
					}
				}
				catch
				{
				}
			}
		}

		private DetailCurveArray DrawCurves(Autodesk.Revit.DB.View drawView, CurveArray curveAry, LegendDirection lengendDir, Transform transform)
		{
			IEnumerable<Curve> enumerable = from Curve curve in curveAry
			select curve.CreateTransformed(transform);
			CurveArray curveArray = new CurveArray();
			foreach (Curve curve2 in enumerable)
			{
				curveArray.Append(curve2);
			}
			return Node.Document.Create.NewDetailCurveArray(drawView, curveArray);
		}

		private List<TextNote> DrawText(Autodesk.Revit.DB.View drawView, Legend legend, Transform scaleMatrix, Transform transform)
		{
			List<TextNoteInfo> textNoteInfoList = legend.TextNoteInfoList;
			TextNoteType textNoteType = Node.Revit.CreateTextNoteType();
			List<TextNote> list = new List<TextNote>();
			foreach (TextNoteInfo textNoteInfo in textNoteInfoList)
			{
				double width = textNoteInfo.m_BoundingBoxWidth * scaleMatrix.Scale.MMtoFeet() * 0.5;
				double height = textNoteInfo.m_BoundingBoxHeight * scaleMatrix.Scale.MMtoFeet() * 0.5;
				XYZ xy = Geometry.TransformPoint(textNoteInfo.m_Center, transform).GetXY();
				TextNote item = this.DrawTextWidthLegend(xy, width, height, textNoteInfo.m_Text, textNoteType, drawView);
				list.Add(item);
			}
			return list;
		}

		private TextNote DrawTextWidthLegend(XYZ ptCenter, double width, double height, string text, TextNoteType textNoteType, Autodesk.Revit.DB.View drawView)
		{
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			double num = height + 100.0.MMtoFeet();
			Arc arc = Arc.Create(ptCenter, num, 0.0, Math.PI*2, XYZ.BasisX, XYZ.BasisY);
			Node.Document.Create.NewDetailCurve(drawView, arc);
			XYZ origin = ptCenter.GetXY() + height * new XYZ(0.0, 1.0, 0.0);
            TextAlignFlags textAlign = (TextAlignFlags)2176;
			TextNote textNode = Node.Revit.Application.ActiveUIDocument.Document.GetTextNode(drawView, origin, new XYZ(1.0, 0.0, 0.0), new XYZ(0.0, 1.0, 0.0), width, textAlign, text);
			if (textNode != null && textNoteType != null)
			{
				textNode.TextNoteType = textNoteType;
			}
			return textNode;
		}

		private List<FilledRegion> DrawRegion(Autodesk.Revit.DB.View drawView, Legend legend, Transform scaleMatrix, Transform transform)
		{
			List<FillRegion> fillRegionList = legend.FillRegionList;
			if (fillRegionList.IsEmpty<FillRegion>())
			{
				return new List<FilledRegion>();
			}
			ElementId filledRegionTypeId = this.GetFilledRegionTypeId();
			return (from fillRegion in fillRegionList
			select this.DrawFilledRegion(fillRegion, filledRegionTypeId, scaleMatrix, transform)).ToList<FilledRegion>();
		}

		private ElementId GetFilledRegionTypeId()
		{
			string typeName = "HY_系统图图例填充";
			Document document = Node.Revit.Application.ActiveUIDocument.Document;
			IEnumerable<FilledRegionType> elements = document.GetElements<FilledRegionType>();
			FilledRegionType filledRegionType = elements.FirstOrDefault((FilledRegionType fp) => string.CompareOrdinal(fp.Name, typeName) == 0);
			if (filledRegionType != null)
			{
				return filledRegionType.Id;
			}
			if (!elements.Any<FilledRegionType>())
			{
				return null;
			}
			filledRegionType = elements.First<FilledRegionType>();
			FilledRegionType filledRegionType2 = filledRegionType.Duplicate(typeName) as FilledRegionType;
			if (filledRegionType2 == null)
			{
				return null;
			}
			FillPatternElement solidPattern = document.GetSolidPattern("实体填充");
			if (solidPattern != null)
			{
				filledRegionType2.FillPatternId = solidPattern.Id;
			}
			try
			{
                filledRegionType2.Color = new Autodesk.Revit.DB.Color(0, 0, 0);
			}
			catch
			{
			}
			return filledRegionType2.Id;
		}

		private FilledRegion DrawFilledRegion(FillRegion fillRegion, ElementId filledRegionTypeId, Transform scaleMatrix, Transform transform)
		{
			CurveLoop curveLoop = new CurveLoop();
			foreach (EdgeInfo edgeInfo in fillRegion.EdgeLoop)
			{
				Curve curve;
				if (edgeInfo.IsArc)
				{
					XYZ xyz = Geometry.TransformPoint(edgeInfo.StartPoint, scaleMatrix);
					XYZ xyz2 = Geometry.TransformPoint(edgeInfo.EndPoint, scaleMatrix);
					XYZ ptCenter = null;
					Geometry.GetCenterWithBulge(xyz, xyz2, edgeInfo.Bulge, ref ptCenter);
					XYZ basisZ = XYZ.BasisZ;
					if (Geometry.LessThan(edgeInfo.Bulge, 0.0))
					{
                        //-XYZ.BasisZ;
					}
					XYZ xyz3 = Geometry.CalculatMidPoint(xyz, xyz2, ptCenter, XYZ.BasisZ);
					curve = Arc.Create(xyz, xyz2, xyz3);
					if (null == curve)
					{
						continue;
					}
				}
				else
				{
					XYZ ptStart = Geometry.TransformPoint(edgeInfo.StartPoint, scaleMatrix);
					XYZ ptEnd = Geometry.TransformPoint(edgeInfo.EndPoint, scaleMatrix);
					curve = Geometry.CreateLine(ptStart, ptEnd);
					if (null == curve)
					{
						continue;
					}
				}
				Curve curve2 = RevitVersionFuncs.CreateTransformed(transform, curve);
				try
				{
					curveLoop.Append(curve2);
				}
				catch (Exception)
				{
					break;
				}
			}
			List<CurveLoop> list = new List<CurveLoop>();
			list.Add(curveLoop);
			try
			{
				return FilledRegion.Create(Node.Revit.Application.ActiveUIDocument.Document, filledRegionTypeId, Node.Revit.Application.ActiveUIDocument.ActiveView.Id, list);
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
			return null;
		}

		private readonly Node.NodeType m_NodeType;

		private readonly List<PipeInfo> m_PipeList = new List<PipeInfo>();

		private CurveArray _legendCurves;

		private List<ElementId> _legendAttachedIds;

		private readonly double _textHeight = 2.5.MMtoFeet();

		private readonly double _textWidth = 2.5.MMtoFeet() * 0.7;

		private readonly XYZ _vecX = new XYZ(1.0, 0.0, 0.0);

		private readonly XYZ _vecY = new XYZ(0.0, 1.0, 0.0);

		private static Dictionary<ElementId, Node.CheckHoleData> _checkHoles;

		public enum NodeType : uint
		{
			NT_NULL,
			NT_PIPEFITTING,
			NT_PIPE_TRANSITION_PIECE,
			NT_PIPEACCESSORY,
			NT_SPRINKLERS,
			NT_PLUMBING_FIXTURES,
			NT_MECHANICAL_EQUIPMENT,
			NT_PIPEFITTING_TRAP_S,
			NT_PIPEFITTING_TRAP_P,
			NT_PIPEACCESSORY_CheckHole,
			NT_PIPEACCESSORY_FloorDrain,
			NT_PIPEACCESSORY_CleanOut
		}

		private class CheckHoleData
		{
			internal ElementId elementId { get; set; }

			internal XYZ P1 { get; set; }

			internal XYZ P2 { get; set; }

			internal void SetPoint(XYZ pt)
			{
				if (this.P1 == null)
				{
					this.P1 = pt;
					return;
				}
				if (!Geometry.IsEqual(pt, this.P1))
				{
					this.P2 = pt;
				}
			}

			internal bool IsValid
			{
				get
				{
					return this.P1 != null && this.P2 != null;
				}
			}
		}
	}
}
